package com.uduemc.biso.node.web.api.service.impl;

import java.io.IOException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.core.utils.ResultUtil;
import com.uduemc.biso.node.core.common.entities.ThemeObject;
import com.uduemc.biso.node.core.common.hostconfig.SearchPageConfig;
import com.uduemc.biso.node.core.common.siteconfig.SiteMenuConfig;
import com.uduemc.biso.node.core.entities.SConfig;
import com.uduemc.biso.node.core.entities.custom.CustomThemeColor;
import com.uduemc.biso.node.core.feign.SConfigFeign;
import com.uduemc.biso.node.core.utils.CustomThemeColorUtil;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.web.api.component.RequestHolder;
import com.uduemc.biso.node.web.api.service.SConfigService;
import com.uduemc.biso.node.web.api.service.ThemeService;

import cn.hutool.core.util.StrUtil;

@Service("sConfigServiceImpl")
public class SConfigServiceImpl implements SConfigService {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private SConfigFeign sConfigFeign;

	@Autowired
	private RequestHolder requestHolder;

	@Autowired
	private ObjectMapper objectMapper;

	@Autowired
	private ThemeService themeServiceImpl;

	@Override
	public SConfig getInfoById(long id) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		RestResult restResult = sConfigFeign.findOne(id);
		SConfig data = RestResultUtil.data(restResult, SConfig.class);
		return data;
	}

	@Override
	public SConfig getCurrentInfo() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		return getInfoBySiteId(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId());
	}

	@Override
	public SConfig getInfoBySiteId(Long siteId) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		return getInfoBySiteId(requestHolder.getHost().getId(), siteId);
	}

	@Override
	public SConfig getInfoBySiteId(Long hostId, Long siteId) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		RestResult restResult = sConfigFeign.findByHostSiteId(hostId, siteId);
		if (restResult.getCode() != 200 || restResult.getData() == null) {
			logger.info(restResult.toString());
			return null;
		}
		return objectMapper.readValue(objectMapper.writeValueAsString(restResult.getData()), SConfig.class);
	}

	@Override
	public JsonResult changeStatus(Long id) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		Long hostId = requestHolder.getHost().getId();
		RestResult restResult = sConfigFeign.findOne(id);
		SConfig sConfig = ResultUtil.data(restResult, SConfig.class);
		if (sConfig == null || sConfig.getHostId().longValue() != hostId) {
			return JsonResult.assistance();
		}

		Short status = sConfig.getStatus().shortValue() == (short) 0 ? (short) 1 : (short) 0;
		sConfig.setStatus(status);
		restResult = sConfigFeign.updateById(sConfig);
		if (restResult.getCode() != 200 || restResult.getData() == null) {
			return JsonResult.assistance();
		}
		sConfig = objectMapper.readValue(objectMapper.writeValueAsString(restResult.getData()), SConfig.class);
		if (sConfig.getStatus().shortValue() == status.shortValue()) {
			return null;
		}
		return JsonResult.assistance();
	}

	@Override
	public boolean changeSiteSeo(Long hostId, Long siteId, short siteSeo)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		SConfig sConfig = getInfoBySiteId(hostId, siteId);
		if (sConfig == null || sConfig.getSiteSeo() == null) {
			logger.error("未找到 sConfig 数据！");
			if (sConfig.getSiteSeo() == null) {
				logger.error("未找到 sConfig 数据！sConfig: " + sConfig.toString());
			}
			return false;
		}
		if (sConfig.getSiteSeo().shortValue() == siteSeo) {
			return true;
		}
		sConfig.setSiteSeo(siteSeo);
		RestResult update = sConfigFeign.updateById(sConfig);
		if (update.getCode() != 200 || update.getData() == null) {
			return false;
		}
		SConfig readValue = objectMapper.readValue(objectMapper.writeValueAsString(update.getData()), SConfig.class);
		if (readValue.getSiteSeo().shortValue() == siteSeo) {
			return true;
		}
		return false;
	}

	@Override
	public boolean changeSiteSeo(short siteSeo) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		return changeSiteSeo(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId(), siteSeo);
	}

	@Override
	public List<SConfig> getCurrentInfosByHostId() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		RestResult restResult = sConfigFeign.findOKByHostId(requestHolder.getHost().getId());
		@SuppressWarnings("unchecked")
		List<SConfig> data = (List<SConfig>) RestResultUtil.data(restResult, new TypeReference<List<SConfig>>() {
		});
		return data;
	}

	@Override
	public boolean changeDefaultSiteAndInfos(long defaultSiteId) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		RestResult restResult = sConfigFeign.changeMainSiteByHostId(requestHolder.getHost().getId(), defaultSiteId);
		boolean data = RestResultUtil.data(restResult, Boolean.class);
		return data;
	}

	@Override
	public SiteMenuConfig getCurrentSiteMenuConfig() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		RestResult restResult = sConfigFeign.findByHostSiteId(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId());
		SConfig data = RestResultUtil.data(restResult, SConfig.class);
		if (data == null || StringUtils.isEmpty(data.getMenuConfig())) {
			return new SiteMenuConfig();
		}
		SiteMenuConfig siteMenuConfig = null;
		try {
			siteMenuConfig = objectMapper.readValue(data.getMenuConfig(), SiteMenuConfig.class);
		} catch (IOException e) {
		}
		if (siteMenuConfig == null) {
			siteMenuConfig = new SiteMenuConfig();
		}
		return siteMenuConfig;
	}

	@Override
	public SConfig updateCurrentSiteMenuConfig(SiteMenuConfig siteMenuConfig)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		SConfig sConfig = getInfoBySiteId(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId());
		if (sConfig == null) {
			return null;
		}
		sConfig.setMenuConfig(objectMapper.writeValueAsString(siteMenuConfig));
		RestResult restResult = sConfigFeign.updateAllById(sConfig);
		return RestResultUtil.data(restResult, SConfig.class);
	}

	@Override
	public SConfig updateAllSiteConfig(SConfig sConfig) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		RestResult restResult = sConfigFeign.updateAllById(sConfig);
		return RestResultUtil.data(restResult, SConfig.class);
	}

	@Override
	public CustomThemeColor getCustomThemeColor() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		SConfig sConfig = getCurrentInfo();
		return getCustomThemeColor(sConfig);
	}

	@Override
	public CustomThemeColor getCustomThemeColor(SConfig sConfig) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		// 获取 sConfig中的 customThemeColorConfig 配置数据
		CustomThemeColor customThemeColorData = null;
		String customThemeColorConfig = sConfig.getCustomThemeColorConfig();
		if (StrUtil.isNotBlank(customThemeColorConfig)) {
			customThemeColorData = objectMapper.readValue(customThemeColorConfig, CustomThemeColor.class);
		}

		// 获取 ThemeObject
		String theme = sConfig.getTheme();
		ThemeObject themeObject = themeServiceImpl.getThemeObject(theme);

		CustomThemeColor makeCustomThemeColor = CustomThemeColorUtil.makeCustomThemeColor(customThemeColorData, themeObject);

		return makeCustomThemeColor;
	}

	@Override
	public JsonResult searchPageConfig() throws IOException {
		Long hostId = requestHolder.getHost().getId();
		Long siteId = requestHolder.getCurrentSite().getId();
		return searchPageConfig(hostId, siteId);
	}

	@Override
	public JsonResult searchPageConfig(long hostId, long siteId) throws IOException {
		SConfig sConfig = getInfoBySiteId(hostId, siteId);
		String searchPageConfigString = sConfig.getSearchPageConfig();
		SearchPageConfig SearchPageConfig = null;
		if (StrUtil.isBlank(searchPageConfigString)) {
			SearchPageConfig = new SearchPageConfig();
		} else {
			try {
				SearchPageConfig = objectMapper.readValue(searchPageConfigString, SearchPageConfig.class);
			} catch (IOException e) {
				e.printStackTrace();
				SearchPageConfig = new SearchPageConfig();
			}
		}
		return JsonResult.ok(SearchPageConfig);
	}

	@Override
	public JsonResult updateSearchPageConfig(String searchPageConfigString) throws IOException {
		Long hostId = requestHolder.getHost().getId();
		Long siteId = requestHolder.getCurrentSite().getId();
		return updateSearchPageConfig(hostId, siteId, searchPageConfigString);
	}

	@Override
	public JsonResult updateSearchPageConfig(long hostId, long siteId, String searchPageConfigString) throws IOException {
		SConfig sConfig = getInfoBySiteId(hostId, siteId);
		if (StrUtil.isNotBlank(searchPageConfigString)) {
			sConfig.setSearchPageConfig(searchPageConfigString);
			updateAllSiteConfig(sConfig);
		}
		return searchPageConfig(hostId, siteId);
	}

}
